﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using UnityEngine;

public class SocketUdp : MonoBehaviour
{
    private static SocketUdp _instance;
    public static SocketUdp Instance
    {
        get
        {
            if (_instance == null)
            {
                GameObject goRestful = new GameObject("SocketUdp");
                _instance = goRestful.AddComponent<SocketUdp>();
            }
            return _instance;
        }
    }

    private UdpClient _udpClient;
    private IPEndPoint _ipendpoint;

    /// <summary>
    /// 初始化UdpClient
    /// </summary>
    /// <param name="ipadr"></param>
    /// <param name="port"></param>
    /// <returns></returns>
    public SocketUdp Connect(string ipadr, int port)
    {
        _ipendpoint = new IPEndPoint(IPAddress.Parse(ipadr), port);
        if (_udpClient == null)
        {
            _udpClient = new UdpClient(0, AddressFamily.InterNetwork);
        }
        return _instance;
    }

    public void DisConnect()
    {
        _udpClient.Close();
        _udpClient.Dispose();
        _udpClient = null;
    }

    /// <summary>
    /// 发送数据
    /// </summary>
    /// <param name="msg"></param>
    public SocketUdp Send(string msg)
    {
        byte[] buffer = Encoding.UTF8.GetBytes(msg);
        _udpClient.Send(buffer, buffer.Length, _ipendpoint);
        return _instance;
    }

    public void Recv(Action<bool, string> actionResult = null)
    {
        StartCoroutine(_Recv(actionResult));
    }


    private IEnumerator _Recv(Action<bool, string> action)
    {
        while (_udpClient != null)
        {
            _udpClient.BeginReceive(UdpDataReceived, action);
            yield return new WaitForSeconds(0.2f);
        }
    }

    private void UdpDataReceived(IAsyncResult ar)
    {
        //如果异步已完成。
        if (ar.IsCompleted)
        {
            //结束挂起的异步接收。
            byte[] receiveByte = _udpClient.EndReceive(ar, ref _ipendpoint);
            //如果收到了数据。
            if (receiveByte.Length > 0)
            {
                //将收到的字节数组转换成字符串。
                string str = Encoding.UTF8.GetString(receiveByte);
                //调用回调函数
                (ar.AsyncState as Action<bool, string>)?.Invoke(true, str);
            }
        }
    }
}
